local Carnival = class("Carnival")


function Carnival:ctor()
end

function Carnival:init()
    self.carnivals = GD:queryCarnivals()
    self.carnivalProgresses = GD:queryCarnivalProgresses()

    self.dayCount = 0
    for k, v in pairs(self.carnivals) do 
        self.dayCount = self.dayCount + 1
    end

    self.sortedProgresses = {}
    for k, v in pairs(self.carnivalProgresses) do
        table.insert(self.sortedProgresses, v)
    end
    table.sort(self.sortedProgresses, function(a, b)
        return checknumber(a.ID) < checknumber(b.ID)
    end)

    self.currentProgressValue = 0
    self.rewardsToGet = {}
    self.tasks = {}
    self.endTime = 0
end

function Carnival:setUUID(uuid)
    self._uuid = uuid
end

function Carnival:taskIDsRedPoint(aTaskIDs)
    local taskArray = string.split(aTaskIDs, ";")
    for i, v in ipairs(taskArray) do
        local t = self.tasks[tostring(v)]
        if t and t:isFinished() and not t:isRewarded() then
            return true
        end
    end 

    return false
end

function Carnival:dayRedPoint(aDay)
    return self:taskIDsRedPoint(self:getTasksByDay(aDay))
end

function Carnival:checkRedPoint()
    -- local taskArray = string.split(self.taskString, ";")
    -- for i, v in ipairs(taskArray) do
    --     local t = UD:getTaskById(checknumber(v))
    --     if t and t:isFinished() and not t:isRewarded() then
    --         return true
    --     end
    -- end 
    if self:taskIDsRedPoint(self.taskString) then
        return true
    end

    if #self.rewardsToGet > 0 then
        return true
    end

    return false
end

function Carnival:refreshTaskString()
    self.taskString = ""
    local c = self:getCurDay()
    for i = 1, c do
        self.taskString = self.taskString..";"..tostring(self:getTasksByDay(i))
    end
end

function Carnival:refreshRedPoint()
    local redPoint = false
    if self:checkRedPoint() then
        redPoint = true
    end

    local rewardModel = app:getInst("RewardModel")
    rewardModel:setRedPoint(self._uuid,redPoint)
end

function Carnival:getTasksByDay(aIndex)
    for k, v in pairs(self.carnivals) do
        if checknumber(v.ID) == aIndex then
            return v.taskIDs
        end
    end
end

function Carnival:hasRewarded(aID)
    if self.rewardsToGet then
        return table.indexof(self.rewardsToGet, aID)
    end
end

function Carnival:getRewardsChangeEventName()
    return "carnival.rewards.change"
end

function Carnival:readTask(t)
    self.tasks[tostring(t.taskId)] = {
        id = t.taskId,
        conf = {
            name=t.name,
            target=t.des,
            finishRewards="",
        },
        taskProgress = {
            {Num=t.step, NeedNum=t.max},
        },
        isFinished = function()
            return checkbool(t.haveGet) == false and t.step >= t.max
        end,
        isRewarded = function()
            return checkbool(t.haveGet)
        end,
        getRewards = function() 
            return t.award
        end,
    }
end

function Carnival:getTask(tid)
    return self.tasks[tostring(tid)]
end

function Carnival:newReqInfo()
    app.session:request("pb_activity.C2S_GetCarnivalInfo", {}, function(msg)
        --dump(msg, "C2S_GetCarnivalInfo")

        self.rewardsToGet = msg.carnival_progress_ids
        self.currentProgressValue = checknumber(msg.ActivityNum)
        self.endTime = math.max(0, checknumber(msg.endTime))
        self.endTimeStamp = app.session:getServerTime()
        self.beginTimeStamp = msg.activityBegTime

        -- self.endTime = 3600*24*3+20000
        

        for i, v in ipairs(msg.tasks) do
            self:readTask(v)
        end

        self:refreshTaskString()
        self:refreshRedPoint()

        EM:notify(self:getRewardsChangeEventName())
    end, nil, function(errMsg)
    end)
end

function Carnival:reqGetAward(id)
    app.session:request("pb_activity.C2S_GetCarnivalAward", {carnival_progress_id = id}, function(msg)
        -- dump(msg, "C2S_GetFatestoneAward")

        if msg.ok then
            self:newReqInfo()
        end
    end, nil, function(errMsg)
    end)
end

function Carnival:getCurDay()
    local day = math.ceil( (app.session:getServerTime() - checknumber(self.beginTimeStamp))/(3600*24) )
    return math.min(math.max(day, 1), self.dayCount) 
end

return Carnival